package com.lcifn.middleware.rpc.transport.invocation;

import com.lcifn.middleware.rpc.server.handler.RequestHandler;
import com.lcifn.middleware.rpc.server.handler.RequestHandlerRegistry;
import com.lcifn.middleware.rpc.transport.command.Command;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 服务端Invocation
 * @author lichao
 * @date 2021/2/1 16:43
 */
@ChannelHandler.Sharable
public class ServerRequestInvocation extends SimpleChannelInboundHandler<Command> {

    private static final Logger logger = LoggerFactory.getLogger(ServerRequestInvocation.class);

    // 请求handler注册器
    private RequestHandlerRegistry registry;

    public ServerRequestInvocation(RequestHandlerRegistry registry) {
        this.registry = registry;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Command command) throws Exception {
        // 1.根据Command类型获取对应的RequestHandler
        RequestHandler handler = registry.get(command.getHeader().getType());
        if (handler == null) {
            throw new Exception(String.format("No handler for request with type %d!", command.getHeader().getType()));
        }
        // 2.RequestHandler执行handler方法
        Command respCommand = handler.handle(command);
        // 3.将响应结果返回客户端
        ctx.channel().writeAndFlush(respCommand).addListener(channelFuture -> {
            if (!channelFuture.isSuccess()) {
                logger.warn("Write response failed!", channelFuture.cause());
                ctx.channel().close();
            }
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }
}
